package com.liaoyifan.core.model;

import com.liaoyifan.core.enums.CoreCodeEnum;
import com.liaoyifan.core.util.RequestContext;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serial;
import java.io.Serializable;
import java.time.Instant;
import lombok.*;

@SuppressWarnings("unused")
@Schema
@Getter
@Builder
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> implements Serializable {

    @Serial private static final long serialVersionUID = 1L;

    private T data;

    @Schema(description = "结果")
    private boolean success;

    @Schema(description = "业务码")
    private Integer code;

    @Schema(description = "消息")
    private String message;

    @Schema(description = "时间戳")
    private Long timestamp;

    @Schema(description = "追踪标识")
    private String trace;

    public static Result<Void> success() {
        return success(null);
    }

    public static <T> Result<T> success(T data) {
        return success(null, data);
    }

    public static <T> Result<T> success(String message, T data) {
        return success(null, message, data);
    }

    public static Result<Void> success(Integer code, String message) {
        return success(code, message, null);
    }

    public static <T> Result<T> success(Integer code, String message, T data) {
        return Result.<T>builder()
                .success(true)
                .code(code)
                .message(message)
                .data(data)
                .timestamp(Instant.now().toEpochMilli())
                .trace(RequestContext.getTrace())
                .build();
    }

    public static Result<Void> error(String message) {
        return error(CoreCodeEnum.UNKNOWN.getCode(), message);
    }

    public static Result<Void> error(Integer code, String message) {
        return error(code, message, null);
    }

    public static <T> Result<T> error(Integer code, String message, T data) {
        return Result.<T>builder()
                .success(false)
                .code(code)
                .message(message)
                .data(data)
                .timestamp(Instant.now().toEpochMilli())
                .trace(RequestContext.getTrace())
                .build();
    }
}
